home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / p4 / p4-1_2b.lha / p4-1.2b / alog / mergelogs.c < prev    next >
C/C++ Source or Header  |  1993-01-25  |  9KB  |  501 lines

  1. /*
  2.  * merge.c:  Program to take mutiple strand format logfiles, sort them,
  3.  *           merge them, and prepend information to the final logfile.
  4.  *
  5.  * Algorithm:
  6.  *     Copy all the negative events at the beginning of the logfiles to a
  7.  *       temporary header file.
  8.  *     Use the unix sort command to sort all the logfiles.
  9.  *     Analyze the data, ignoring all events that are not > 0.
  10.  *     Print to stdout the results of the analyzation, the header file,
  11.  *       and the sorted log entries.
  12.  *
  13.  *    Modified Summer 1990 by James Arthur Kohl
  14.  *        to combine count collection more efficiently.
  15.  *
  16.  *        Now it's REAL fast!
  17.  */
  18. #include <stdio.h>
  19. #include <ctype.h>           /* for calling isdigit()             */
  20. #include "alog_evntdfs.h"       /* Logfile definitions */
  21.  
  22. #define FALSE 0
  23. #define TRUE !FALSE
  24. #define MAX(x,y)    ( (x) > (y) ? (x) : (y) )
  25.  
  26. #define C_DATA_LEN 50
  27.  
  28. #define DO_NEGATIVE 1
  29. #define IGNORE_NEGATIVE 2
  30.  
  31. struct log_entry
  32. {
  33.     int proc_id;
  34.     int task_id;
  35.     int event;
  36.     int i_data;
  37.     char c_data[C_DATA_LEN];
  38.     int time_slot;
  39.     unsigned long time;
  40. };
  41.  
  42. struct list_struct
  43. {
  44.     struct log_entry entry;
  45.     struct list_struct *next;
  46. } *log_table;
  47.  
  48. struct list_struct *log_ptr;
  49.  
  50. int entry_tot;
  51.  
  52. main(argc,argv)
  53. int argc;
  54. char *argv[];
  55. {
  56.     FILE *headerfp;
  57.  
  58.     char headerfile[255];
  59.  
  60.     int pid;
  61.  
  62.     if ( argc <= 1 ) 
  63.         usage();
  64.  
  65.     pid = getpid();
  66.  
  67.     sprintf(headerfile,"/usr/tmp/log.header.%d",pid);
  68.  
  69.     if ( (headerfp=fopen(headerfile,"w")) == NULL )
  70.     {
  71.         fprintf(stderr,"merge: unable to create temp file %s.\n",headerfile);
  72.         exit(0);
  73.     }
  74.  
  75.     combine_files(argc,argv,headerfp);
  76.  
  77.     if ( (headerfp=fopen(headerfile,"r")) == NULL )
  78.     {
  79.         fprintf(stderr,"merge: unable to read temp file %s.\n",headerfile);
  80.         exit(0);
  81.     }
  82.  
  83.     fprintf(stderr,"Analyzing.\n");
  84.     analyze(headerfp);
  85.  
  86.     fclose(headerfp);
  87.     unlink(headerfile); 
  88. } /* main */
  89.  
  90.  
  91. combine_files(argc,argv,headerfp)
  92. int argc;
  93. char *argv[];
  94. FILE *headerfp;
  95. {
  96.     FILE *in;
  97.  
  98.     struct list_struct **files;
  99.     struct list_struct *last;
  100.     struct list_struct *ptr;
  101.  
  102.     struct log_entry *entry;
  103.  
  104.     unsigned long min_time;
  105.  
  106.     int min_event;
  107.     int min_slot;
  108.     int min;
  109.  
  110.     int all_eof;
  111.     int eof_flag;
  112.     int negflag;
  113.     int num;
  114.     int i;
  115.  
  116.     num = argc - 1;
  117.  
  118.     if ( (files=(struct list_struct **)
  119.         malloc(num * sizeof(struct list_struct *))) == NULL )
  120.     {
  121.         fprintf(stderr,"merge: unable to allocate input data array.\n");
  122.         exit(0);
  123.     }
  124.  
  125.     for ( i=0 ; i < num ; i++ )
  126.     {
  127.         fprintf(stderr,"Reading %s\n",argv[i+1]);
  128.  
  129.         if ( (in=fopen(argv[i+1],"r")) == NULL )
  130.         {
  131.             fprintf(stderr,"merge: unable to read data file %s.\n",argv[i+1]);
  132.             exit(0);
  133.         }
  134.  
  135.         if ( (files[i]=(struct list_struct *)
  136.             malloc(sizeof(struct list_struct))) == NULL )
  137.         {
  138.             fprintf(stderr,"merge: unable to allocate list struct.\n");
  139.             exit(0);
  140.         }
  141.  
  142.         ptr = files[i];
  143.  
  144.         last = NULL;
  145.  
  146.         do
  147.         {
  148.             read_logentry(in,&(ptr->entry),DO_NEGATIVE);
  149.  
  150.             if ( !(eof_flag=feof(in)) )
  151.             {
  152.                 if ( (ptr->next=(struct list_struct *)
  153.                     malloc(sizeof(struct list_struct))) == NULL )
  154.                 {
  155.                     fprintf(stderr,"merge: unable to allocate list struct.\n");
  156.                     exit(0);
  157.                 }
  158.  
  159.                 last = ptr;
  160.  
  161.                 ptr = ptr->next;
  162.             }
  163.  
  164.             else
  165.             {
  166.                 if ( last != NULL )
  167.                     last->next = NULL;
  168.  
  169.                 else
  170.                     files[i] = NULL;
  171.  
  172.                 free(ptr);
  173.                 ptr = NULL;
  174.             }
  175.         }
  176.         while ( !eof_flag );
  177.  
  178.         fclose(in);
  179.     }
  180.  
  181.     fprintf(stderr,"Sorting.\n");
  182.  
  183.     all_eof = 0;
  184.  
  185.     do
  186.     {
  187.         negflag = 0;
  188.  
  189.         for ( i=0 ; i < num ; i++ )
  190.         {
  191.             if ( files[i] == NULL )
  192.                 continue;
  193.  
  194.             entry = &(files[i]->entry);
  195.  
  196.             if ( entry->event < 0 )
  197.             {
  198.                 negflag++;
  199.  
  200.                 fprintf(headerfp,"%d %d %d %d %d %lu %s\n",entry->event,
  201.                     entry->proc_id,entry->task_id,entry->i_data,
  202.                     entry->time_slot,entry->time,entry->c_data);
  203.  
  204.                 files[i] = files[i]->next;
  205.  
  206.                 if ( files[i] == NULL )
  207.                     all_eof++;
  208.             }
  209.         }
  210.     }
  211.     while ( negflag && all_eof < num );
  212.  
  213.     fclose(headerfp);
  214.  
  215.     log_table = log_ptr = NULL;
  216.  
  217.     entry_tot = 0;
  218.  
  219.     while ( all_eof < num )
  220.     {
  221.         min_event = 0;
  222.         min_time = 0;
  223.         min_slot = 0;
  224.  
  225.         min = -1;
  226.  
  227.         for ( i=0 ; i < num ; i++ )
  228.         {
  229.             if ( files[i] == NULL )
  230.                 continue;
  231.  
  232.             entry = &(files[i]->entry);
  233.  
  234.             if (
  235.                 (entry->time_slot == min_slot && entry->time < min_time)
  236.                 || entry->time_slot < min_slot
  237.                 || min == -1
  238.                 || (entry->time_slot == min_slot && entry->time == min_time
  239.                     && entry->event < min_event)
  240.                 )
  241.             {
  242.                 min_event = entry->event;
  243.                 min_time = entry->time;
  244.                 min_slot = entry->time_slot;
  245.  
  246.                 min = i;
  247.             }
  248.         }
  249.  
  250.         if ( log_ptr == NULL )
  251.         {
  252.             log_table = log_ptr = files[min];
  253.  
  254.             files[min] = files[min]->next;
  255.         }
  256.  
  257.         else
  258.         {
  259.             log_ptr->next = files[min];
  260.  
  261.             files[min] = files[min]->next;
  262.  
  263.             log_ptr = log_ptr->next;
  264.         }
  265.  
  266.         log_ptr->next = NULL;
  267.  
  268.         entry_tot++;
  269.  
  270.         if ( files[min] == NULL )
  271.             all_eof++;
  272.     }
  273.  
  274.     fprintf(stderr, "  %d total entries\n", entry_tot);
  275. }
  276.  
  277.  
  278. usage()
  279. {
  280.     fprintf(stderr,"mergelogs: mergelogs infile1 infile2 ...\n");
  281.     fprintf(stderr,"  writes to stdout\n");
  282.  
  283.     exit(0);
  284. }
  285.  
  286.  
  287. /* analyze:  At this point, we have one large sorted file called :tname:.
  288.  *           We want to prepend certain data to it.
  289.  *           We also want to prepend the data from the file pointed to
  290.  *             by :headerfp:.
  291.  *           See balance:/usr/local/trace/README for info.
  292.  *           
  293.  */
  294. analyze(headerfp)
  295. FILE *headerfp;
  296. {
  297.     struct log_entry *entry;
  298.  
  299.     int proc_tot, task_tot, time_slot_tot, event_tot;
  300.     int i;
  301.  
  302.     get_counts(&proc_tot,&task_tot,&event_tot,&time_slot_tot);
  303.  
  304.     fprintf(stderr, "  %d separate processors\n",  proc_tot);
  305.     fprintf(stderr, "  %d separate tasks\n",  task_tot);
  306.     fprintf(stderr, "  %d event types\n", event_tot);
  307.  
  308.     fprintf(stdout,"%d %d %d %d %d %lu\n",NUM_EVENTS,0,0,entry_tot,0,0L);
  309.     fprintf(stdout,"%d %d %d %d %d %lu\n",NUM_PROCS,0,0,proc_tot,0,0L);
  310.     fprintf(stdout,"%d %d %d %d %d %lu\n",NUM_TASKS,0,0,task_tot,0,0L);
  311.     fprintf(stdout,"%d %d %d %d %d %lu\n",NUM_EVTYPES,0,0,event_tot,0,0L); 
  312.     fprintf(stdout,"%d %d %d %d %d %lu\n",START_TIME,0,0,0,0,
  313.         log_table->entry.time);
  314.     fprintf(stdout,"%d %d %d %d %d %lu\n",END_TIME,0,0,0,0,
  315.         log_ptr->entry.time);
  316.     fprintf(stdout,"%d %d %d %d %d %lu\n",NUM_CYCLES,0,0,time_slot_tot,0,0L);
  317.  
  318.     dump_header(headerfp);
  319.  
  320.     log_ptr = log_table;
  321.  
  322.     while ( log_ptr != NULL )
  323.     {
  324.         entry = &(log_ptr->entry);
  325.  
  326.         fprintf(stdout,"%d %d %d %d %d %lu  %s\n",entry->event, 
  327.             entry->proc_id,entry->task_id,entry->i_data,
  328.             entry->time_slot,entry->time,entry->c_data);
  329.     
  330.         log_ptr = log_ptr->next;
  331.     }
  332. } /* analyze */  
  333.  
  334.  
  335. dump_header(headerfp)
  336. FILE *headerfp;
  337. {
  338.     char buf[512];
  339.     int len;
  340.  
  341.     do
  342.     {
  343.         if ( len=fread(buf,sizeof(char),512,headerfp) )
  344.             fwrite(buf,sizeof(char),len,stdout);
  345.     }
  346.     while ( !feof(headerfp) && len );
  347. } /* dump_header */
  348.     
  349.  
  350. read_logentry(fp,table,do_negs)
  351. FILE *fp;
  352. struct log_entry *table;
  353. int do_negs;
  354. {
  355.     char buf[81];
  356.     char *cp;
  357.  
  358.     int i;
  359.  
  360.     do
  361.     {    
  362.         fscanf(fp,"%d %d %d %d %d %lu",
  363.             &(table->event),&(table->proc_id),&(table->task_id),
  364.             &(table->i_data),&(table->time_slot),&(table->time));
  365.  
  366.         cp = table->c_data;
  367.  
  368.         i = 0;
  369.  
  370.         do
  371.         {
  372.             fscanf(fp,"%c",cp);
  373.         }
  374.         while ( *cp == ' ' || *cp == '\t' );
  375.  
  376.         i++;
  377.  
  378.         while ( *cp != '\n' && i < C_DATA_LEN )
  379.         {
  380.             fscanf(fp,"%c",++cp);
  381.  
  382.             i++;
  383.         }
  384.  
  385.         *cp = '\0';
  386.  
  387.         /*
  388.         if ( !feof(fp) && table->event == 0 )
  389.             fprintf(stderr,"0 reading in.\n");
  390.         */
  391.     }
  392.     while( table->event < 0 && do_negs == IGNORE_NEGATIVE && !feof(fp) );
  393. }
  394.  
  395.  
  396. get_counts(ptot,ttot,etot,tstot)
  397. int *ptot,*ttot,*etot,*tstot;
  398. {
  399.     struct list_struct *ptr;
  400.  
  401.     struct log_entry *entry;
  402.     struct log_entry *last;
  403.  
  404.     int *p, *t, *e;
  405.  
  406.     int flag;
  407.     int val;
  408.     int i,j;
  409.  
  410.     if ( (p=(int *)malloc(sizeof(int) * entry_tot)) == NULL )
  411.     {
  412.         fprintf(stderr,"Not enough memory.\n");
  413.         exit(0);
  414.     }
  415.  
  416.     if ( (t=(int *)malloc(sizeof(int) * entry_tot)) == NULL )
  417.     {
  418.         fprintf(stderr,"Not enough memory.\n");
  419.         exit(0);
  420.     }
  421.  
  422.     if ( (e=(int *)malloc(sizeof(int) * entry_tot)) == NULL )
  423.     {
  424.         fprintf(stderr,"Not enough memory.\n");
  425.         exit(0);
  426.     }
  427.  
  428.     for ( i=0 ; i < entry_tot ; i++ )
  429.     {
  430.         p[i] = t[i] = e[i] = 0;
  431.     }
  432.  
  433.     *ptot = *ttot = *etot = 0;
  434.  
  435.     *tstot = 1;
  436.  
  437.     ptr = log_table;
  438.  
  439.     last == NULL;
  440.  
  441.     while ( ptr != NULL )
  442.     {
  443.         entry = &(ptr->entry);
  444.  
  445.         flag = 0;
  446.  
  447.         val = entry->proc_id;
  448.  
  449.         for ( j=0 ; j < *ptot && !flag ; j++ )
  450.         {
  451.             if ( p[j] == val )
  452.                 flag++;
  453.         }
  454.  
  455.         if ( !flag )
  456.         {
  457.             p[(*ptot)++] = val;
  458.         }
  459.  
  460.         flag = 0;
  461.  
  462.         val = entry->task_id;
  463.  
  464.         for ( j=0 ; j < *ttot && !flag ; j++ )
  465.         {
  466.             if ( t[j] == val )
  467.                 flag++;
  468.         }
  469.  
  470.         if ( !flag )
  471.         {
  472.             t[(*ttot)++] = val;
  473.         }
  474.  
  475.         flag = 0;
  476.  
  477.         val = entry->event;
  478.  
  479.         for ( j=0 ; j < *etot && !flag ; j++ )
  480.         {
  481.             if ( e[j] == val )
  482.                 flag++;
  483.         }
  484.  
  485.         if ( !flag )
  486.         {
  487.             e[(*etot)++] = val;
  488.         }
  489.  
  490.                 /* printf("tstot=%d *tstot=%d\n",tstot,*tstot); */
  491.         if ( (last != NULL) && (entry->time_slot != last->time_slot) )
  492.                         *tstot = *tstot + 1;
  493.             /*  (*tstot)++;  */
  494.  
  495.         last = entry;
  496.  
  497.         ptr = ptr->next;
  498.     }
  499.         return(0);
  500. }
  501.